package fun.flyee.android.pengshan.utils;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Base64;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Files {

    public static void download(Context context, final String iconUrl, final DownLoadResultCallback callback) {
        String iconFileName = "task_" + MD5.md5(iconUrl) + ".jpg";
        final File iconFile = new File(context.getCacheDir(), iconFileName);
        if (!iconFile.exists()) {
            download(context, iconUrl, iconFile, callback);
        } else {
            callback.downloaded(iconFile);
        }
    }

    public static void download(Context context, final String fileUrl, final File dstFile, final DownLoadResultCallback callback) {
        new Thread() {
            public void run() {
                try {
                    URL iconURL = new URL(fileUrl);
                    HttpURLConnection connection = (HttpURLConnection) iconURL.openConnection();
                    InputStream iconIs = connection.getInputStream();
                    FileOutputStream iconOs = new FileOutputStream(dstFile);
                    byte[] bytes = new byte[1024];
                    int length;
                    while ((length = iconIs.read(bytes)) != -1) {
                        iconOs.write(bytes, 0, length);
                    }
                    iconOs.flush();
                    iconIs.close();
                    iconOs.close();
                    callback.downloaded(dstFile);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                    callback.downloaded(null);
                } catch (IOException e) {
                    e.printStackTrace();
                    callback.downloaded(null);
                }
            }
        }.start();
    }

    public static void httpGet(final String url, final HttpCallback callback) {
        new Thread() {
            public void run() {
                try {
                    URL iconURL = new URL(url);
                    HttpURLConnection connection = (HttpURLConnection) iconURL.openConnection();
                    InputStream in = connection.getInputStream();
                    InputStreamReader reader = new InputStreamReader(in);
                    BufferedReader br = new BufferedReader(reader);
                    String result = "";
                    String line = null;
                    while ((line = br.readLine()) != null) {
                        result += line;
                    }
                    callback.get(result);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                    callback.get(null);
                } catch (IOException e) {
                    e.printStackTrace();
                    callback.get(null);
                }
            }
        }.start();
    }

    public static String fileRead(File file) {
        FileReader reader = null;
        try {
            reader = new FileReader(file);
            String result = new BufferedReader(reader).readLine();
            return result;
        } catch (FileNotFoundException fne) {
            fne.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
    }

    public static void fileWrite(File file, String text) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(file, false);
            writer.write(text);
            writer.flush();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
    }

    public interface DownLoadResultCallback {
        void downloaded(File file);
    }

    public interface HttpCallback {
        void get(String text);
    }

    public static boolean unzip(File srcFile, File dstFolder) {
        try {
            FileInputStream fis = new FileInputStream(srcFile);
            return unzip(fis, dstFolder);
        } catch (FileNotFoundException e) {
            return false;
        }
    }

    public static boolean unzip(InputStream fis, File dstFolder) {
        int BUFFER = 4096; //这里缓冲区我们使用4KB，
        String strEntry; //保存每个zip的条目名称
        try {
            BufferedOutputStream dest; //缓冲输出流
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
            ZipEntry entry; //每个zip条目的实例
            while ((entry = zis.getNextEntry()) != null) {
                try {
                    int count;
                    byte data[] = new byte[BUFFER];
                    strEntry = entry.getName();
                    File entryFile = new File(dstFolder, strEntry);
                    File entryDir = new File(entryFile.getParent());
                    if (!entryDir.exists()) {
                        entryDir.mkdirs();
                    }
                    long length = entryFile.length();
                    long size = entry.getSize();
                    if (length == size) {
                        continue;
                    }
                    FileOutputStream fos = new FileOutputStream(entryFile);
                    dest = new BufferedOutputStream(fos, BUFFER);
                    while ((count = zis.read(data, 0, BUFFER)) != -1) {
                        dest.write(data, 0, count);
                    }
                    dest.flush();
                    dest.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            zis.close();
            return true;
        } catch (Exception cwj) {
            cwj.printStackTrace();
            return false;
        }
    }

    public static boolean copy(File srcFile, File dstFile) {
        try {
            FileInputStream fis = new FileInputStream(srcFile);
            copy(fis, dstFile);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static void copy(InputStream in, File dstFile) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(dstFile);
            //从in中批量读取字节，放入到buf这个字节数组中，
            // 从第0个位置开始放，最多放buf.length个 返回的是读到的字节的个数
            byte[] buf = new byte[8 * 1024];
            int len = 0;
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e) {
                System.out.println("关闭输入流错误！");
            }
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {
                System.out.println("关闭输出流错误！");
            }
        }
    }

    public static void deleteChildrenFiles(File dir) {
        if (!dir.exists()) return;
        if (dir.listFiles().length > 0) {
            for (File file : dir.listFiles()) {
                if (file.isDirectory()) {
                    deleteChildrenFiles(file);
                    file.delete();
                } else {
                    file.delete();
                }
            }
        }
        dir.delete();
    }

    public static String getFileMD5(File updateFile) {
        InputStream is;
        try {
            is = new FileInputStream(updateFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }

        return getFileMD5(is);
    }

    public static String getFileMD5(InputStream is) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }

        byte[] buffer = new byte[8192];
        int read;
        try {
            while ((read = is.read(buffer)) > 0) {
                digest.update(buffer, 0, read);
            }
            byte[] md5sum = digest.digest();
            BigInteger bigInt = new BigInteger(1, md5sum);
            String output = bigInt.toString(16);
            // Fill to 32 chars
            output = String.format("%32s", output).replace(' ', '0');
            return output;
        } catch (IOException e) {
            throw new RuntimeException("Unable to process file for MD5", e);
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String img2base64(String path) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        options.inSampleSize = calculateInSampleSize(options, 128, 128);
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeFile(path, options);
        String base64 = bitmapToBase64(bitmap);
        bitmap.recycle();
        return base64;
    }

    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        int height = options.outHeight;
        int width = options.outWidth;
        int inSampleSize = 1;
        if (width < 100) {
            return inSampleSize;
        } else {
            int heightRatio;
            if (width > height && reqWidth < reqHeight || width < height && reqWidth > reqHeight) {
                heightRatio = reqWidth;
                reqWidth = reqHeight;
                reqHeight = heightRatio;
            }

            if (height > reqHeight || width > reqWidth) {
                heightRatio = Math.round((float) height / (float) reqHeight);
                int widthRatio = Math.round((float) width / (float) reqWidth);
                inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio;
            }

            return inSampleSize;
        }
    }

    public static String bitmapToBase64(Bitmap bitmap) {
        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.NO_WRAP);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static String getRealPathFromURI(Context context, Uri contentURI) {
        String result;
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(contentURI, null, null, null, null);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        if (cursor == null) {
            result = contentURI.getPath();
        } else {
            cursor.moveToFirst();
            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            result = cursor.getString(idx);
            cursor.close();
        }
        return result;
    }

}
